package com.examination.client.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.examination.client.config.AliyunOssProperties;
import com.examination.client.domian.dto.UserTokenDTO;
import com.examination.client.entity.CourierInfo;
import com.examination.client.enums.CourierStatusEnum;
import com.examination.client.enums.DeleteStatusEnum;
import com.examination.client.service.IAliyunOssService;
import com.examination.client.service.ICourierDeliveryImageService;
import com.examination.client.service.ICourierInfoService;
import com.examination.client.util.IdUtil;
import com.examination.client.util.UserInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author fengfeixiang
 * @Description:
 * @Auther: Jacob feixiang.feng
 * @Date: 2021/10/20
 */
@Slf4j
@Service
public class AliyunOssServiceImpl implements IAliyunOssService {

    @Autowired
    private AliyunOssProperties aliyunOssProperties;

    @Resource
    ICourierDeliveryImageService courierDeliveryImageService;

    @Resource
    ICourierInfoService courierInfoService;

    @Override
    public String upload(MultipartFile file, String courierCode, String courierStatus)throws Exception {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();
        String fileHost = aliyunOssProperties.getFileHost();
        String domain = aliyunOssProperties.getDomain();
        log.info("OSS文件上传开始file{}", file);
        log.info("OSS文件上传开始courierCode{}", courierCode.contains(",") ? courierCode.split(",")[0] : courierCode);
        log.info("OSS文件上传开始courierStatus{}", courierStatus);
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //上传文件
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String filename = StringUtils.join(fileHost, IdUtil.randomUUID(),suffix);
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, filename, file.getInputStream()));
            String url = "https://" + domain + "/" + filename;
            if (null != result) {
                log.info("OSS文件上传成功,OSS地址:{}：" + url);
                int status = Integer.parseInt(courierStatus);
                if (status == 2) {
                    log.info("OSS文件上传成功,OSS地址:{}：-- 保存图片 ---- " + url);
                    courierDeliveryImageService.saveDeliveryImage(url, courierCode, status);
//                    LambdaQueryWrapper<CourierInfo> queryWrapper = new LambdaQueryWrapper<>();
//                    queryWrapper.eq(CourierInfo::getCourierCode, courierCode);
//                    queryWrapper.eq(CourierInfo::getDeleteStatus, DeleteStatusEnum.NOT_DELETED.getCode());
//                    List<CourierInfo> courierList = courierInfoService.list(queryWrapper);
//                    for (CourierInfo courierInfo : courierList) {
//                        if(Objects.nonNull(courierInfo.getNextSiteId())){
//                            courierInfo.setCourierStatus(CourierStatusEnum.DELIVERY.getCode());
//                        }else {
//                            courierInfo.setCourierStatus(CourierStatusEnum.HAVE_RECEIVED.getCode());
//                        }
//                        courierInfoService.updateById(courierInfo);
//                    }
                }
                return url;
            }
        } catch (OSSException oe) {
            log.info("OSS文件上传失败");
            log.error(oe.getMessage());
        } catch (ClientException ce) {
            log.info("OSS文件上传失败");
            log.error(ce.getMessage());
        } finally {
            ossClient.shutdown();
        }
        log.info("OSS文件上传失败");
        return null;
    }

    @Override
    public String uploadAsy(MultipartFile file, String id) throws Exception {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();
        String fileHost = aliyunOssProperties.getFileHost();
        String domain = aliyunOssProperties.getDomain();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //上传文件
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String filename = StringUtils.join(fileHost, IdUtil.randomUUID(),suffix);
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, filename, file.getInputStream()));
            if (null != result) {
                String url = "https://" + domain + "/" + filename;
                LambdaQueryWrapper<CourierInfo> query = new LambdaQueryWrapper<>();
                query.eq(CourierInfo::getId, id);
                query.eq(CourierInfo::getDeleteStatus, DeleteStatusEnum.NOT_DELETED.getCode());
                CourierInfo courierInfo = courierInfoService.getOne(query);
                courierInfo.setStorageImageUrl(url);
                courierInfoService.updateById(courierInfo);
                return url;
            }
        } catch (OSSException oe) {
            log.info("uploadAsy OSS文件上传失败");
            log.error(oe.getMessage());
        } catch (ClientException ce) {
            log.info("uploadAsy OSS文件上传失败");
            log.error(ce.getMessage());
        } finally {
            ossClient.shutdown();
        }
        log.info("uploadAsy OSS文件上传失败");
        return null;
    }

    @Override
    public String uploadAsyCode(MultipartFile file, String code) throws Exception {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();
        String fileHost = aliyunOssProperties.getFileHost();
        String domain = aliyunOssProperties.getDomain();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //上传文件
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String filename = StringUtils.join(fileHost, IdUtil.randomUUID(),suffix);
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, filename, file.getInputStream()));
            if (null != result) {
                String url = "https://" + domain + "/" + filename;
                LambdaQueryWrapper<CourierInfo> query = new LambdaQueryWrapper<>();
                query.eq(CourierInfo::getCourierCode, code);
                query.isNull(CourierInfo::getNextSiteId);
                query.eq(CourierInfo::getDeleteStatus, DeleteStatusEnum.NOT_DELETED.getCode());
                CourierInfo courierInfo = courierInfoService.getOne(query);
                courierInfo.setStorageImageUrl(url);
                courierInfoService.updateById(courierInfo);
                return url;
            }
        } catch (OSSException oe) {
            log.info("uploadAsy OSS文件上传失败");
            log.error(oe.getMessage());
        } catch (ClientException ce) {
            log.info("uploadAsy OSS文件上传失败");
            log.error(ce.getMessage());
        } finally {
            ossClient.shutdown();
        }
        log.info("uploadAsy OSS文件上传失败");
        return null;
    }


    @Override
    public void downloadFile(String objectName, String localFileName) {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();

        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    @Override
    public Boolean delFile(String filePath) {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();

        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        boolean exist = ossClient.doesObjectExist(bucketName, filePath);
        if (!exist) {
            log.error("文件不存在,filePath={}", filePath);
            return false;
        }
        log.info("删除文件,filePath={}", filePath);
        ossClient.deleteObject(bucketName, filePath);
        ossClient.shutdown();
        return true;
    }

    @Override
    public Boolean delFileList(java.util.List<String> keys) {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();

        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        try {
            // 删除文件。
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
            java.util.List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            ossClient.shutdown();
        }
        return true;

    }

    @Override
    public java.util.List<String> fileFolder(String fileName) {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();

        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

        listObjectsRequest.setDelimiter("/");
        if (StringUtils.isNotBlank(fileName)) {
            listObjectsRequest.setPrefix(fileName + "/");
        }

        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        java.util.List<String> list = new ArrayList<>();
        for (String commonPrefix : listing.getCommonPrefixes()) {
            String newCommonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1);
            String[] s = newCommonPrefix.split("/");
            list.add(s[1]);
        }
        ossClient.shutdown();
        return list;
    }

    @Override
    public List<String> listFile(String fileHost) {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();
        String domain = aliyunOssProperties.getDomain();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

        listObjectsRequest.setPrefix(fileHost + "/");
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        List<String> list = new ArrayList<>();
        for (int i = 0; i < listing.getObjectSummaries().size(); i++) {
            if (i == 0) {
                continue;
            }
            String url = "https://" + domain + "/" + listing.getObjectSummaries().get(i).getKey();
            list.add(url);
        }
        ossClient.shutdown();
        return list;
    }

    @Override
    public String getUrl(String objectName) {
        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();


        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 100);
        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
        req.setExpiration(expiration);
        URL signedUrl = ossClient.generatePresignedUrl(req);
        // 关闭OSSClient。
        log.info("------OSS文件文件信息--------:{}",signedUrl.toString());
        ossClient.shutdown();
        if (signedUrl != null) {
            return signedUrl.toString();
        }
        return null;
    }


    public String getSuffix(MultipartFile fileupload) {
        String originalFilename = fileupload.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        return suffix;
    }

    @Override
    public String createFolder(String folder) {

        String endpoint = aliyunOssProperties.getEndpoint();
        String accessKeyId = aliyunOssProperties.getAccessKeyId();
        String accessKeySecret = aliyunOssProperties.getAccessKeySecret();
        String bucketName = aliyunOssProperties.getBucketName();

        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        final String keySuffixWithSlash = folder;
        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            // 创建文件夹
            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            log.info("创建文件夹成功");
            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            ossClient.shutdown();
            return fileDir;
        }
        return keySuffixWithSlash;
    }

}
